package service;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collection;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.thoughtworks.xstream.XStream;

import core.Planet;

public class PlanetServiceImpl implements PlanetService {

	// Logger
	private static Logger LOGGER = LoggerFactory.getLogger(PlanetService.class);

	/** Default options file name */
	private static final String PLANETS_FILE = "planets.xml";
	/** Default directory */
	private static final String DIR = "src/main/resources/";

	@SuppressWarnings("unchecked")
	@Override
	public List<Planet> loadPlanets() {

		List<Planet> planets = Lists.newArrayList();
		File planetsFile = new File(DIR + PLANETS_FILE);
		try {
			XStream xstream = getInstance();
			FileReader fis = new FileReader(planetsFile);
			try {
				planets = (List<Planet>) xstream.fromXML(fis);
				LOGGER.debug("Loaded planets : {} ", planets, planetsFile.toURI());
			} finally {
				fis.close();
			}

		} catch (FileNotFoundException e) {
			LOGGER.debug(e.getLocalizedMessage());
		} catch (IOException ioe) {
			LOGGER.debug(ioe.getLocalizedMessage());
		}

		return planets;
	}

	@Override
	public Planet loadPlanet(final String name) {

		Predicate<Planet> planetName = new Predicate<Planet>() {
			@Override
			public boolean apply(Planet planet) {
				return planet.getName().equals(name);
			}
		};
		Collection<Planet> filter = Collections2.filter(loadPlanets(), planetName);
		assert filter.size() == 1;
		return filter.iterator().next();
	}

	/**
	 * Retourne l'instance de load des planetes
	 * 
	 * @return
	 */
	public XStream getInstance() {
		XStream xstream = new XStream();
		xstream.alias("planets", List.class);
		xstream.alias("planet", Planet.class);
		xstream.useAttributeFor(Planet.class, "name");
		xstream.aliasField("distance", Planet.class, "distanceFromSun");
		return xstream;
	}

}
